/* Copyright (c) 2022 渝州大数据实验室
 *
 * Lanius is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *
 *     http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.yzbdl.lanius.orchestrate.serv.service.resource.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.yzbdl.lanius.orchestrate.serv.dto.resource.ServerPageDto;
import org.yzbdl.lanius.orchestrate.serv.entity.resource.ServerEntity;
import org.yzbdl.lanius.orchestrate.serv.entity.resource.ServerProgramEntity;
import org.yzbdl.lanius.orchestrate.serv.enums.ResourceDataStatusEnum;
import org.yzbdl.lanius.orchestrate.serv.mapper.resource.ServerMapper;
import org.yzbdl.lanius.orchestrate.serv.mapper.resource.ServerProgramMapper;
import org.yzbdl.lanius.orchestrate.serv.service.resource.ServerService;
import org.yzbdl.lanius.orchestrate.common.exception.runtime.BusinessException;
import org.yzbdl.lanius.orchestrate.common.utils.ExceptionUtil;
import org.yzbdl.lanius.orchestrate.common.utils.SpecialCharacterUtil;

import java.util.Objects;

/**
 * @author zhuhongji
 * @since 2022-03-29 14:46
 */
@Service
@AllArgsConstructor
public class ServerServiceImpl extends ServiceImpl<ServerMapper, ServerEntity> implements ServerService {

    private final ServerProgramMapper serverProgramMapper;

    @Override
    public Boolean addServer(ServerEntity serverEntity) {
        LambdaQueryWrapper<ServerEntity> queryWrapper = new QueryWrapper<ServerEntity>().lambda()
                .eq(ServerEntity::getServerName, serverEntity.getServerName())
                .eq(ServerEntity::getDeleted, false);
        ExceptionUtil.checkParam(!this.baseMapper.exists(queryWrapper), "已存在同样的主机名称，请重新输入！");
        LambdaQueryWrapper<ServerEntity> queryIpWrapper = new QueryWrapper<ServerEntity>().lambda()
                .eq(ServerEntity::getServerIp, serverEntity.getServerIp())
                .eq(ServerEntity::getServerPort, serverEntity.getServerPort())
                .eq(ServerEntity::getAccountName, serverEntity.getAccountName())
                .eq(ServerEntity::getDeleted, false);
        ExceptionUtil.checkParam(!this.baseMapper.exists(queryIpWrapper),
                "已存在IP地址、主机端口、用户名三项同时相同的主机信息，请重新输入！");
        if(Objects.isNull(serverEntity.getStatus())){
            serverEntity.setStatus(ResourceDataStatusEnum.NORMAL.getCode());
        }
        serverEntity.setDeleted(false);
        return this.save(serverEntity);
    }

    @Override
    public Boolean deleteServer(Long id) {
        LambdaQueryWrapper<ServerProgramEntity> queryWrapper = new QueryWrapper<ServerProgramEntity>().lambda()
                .eq(ServerProgramEntity::getServerId, id)
                .eq(ServerProgramEntity::getDeleted, false);
        if(serverProgramMapper.exists(queryWrapper)){
            throw new BusinessException("主机配置了服务节点，请到服务节点管理模块，将该主机下的服务节点全部删除后，再来进行主机删除操作！");
        }
        return this.updateById(ServerEntity.builder().id(id).deleted(true).build());
    }

    @Override
    public ServerEntity getServer(Long id) {
        return this.getById(id);
    }

    @Override
    public IPage<ServerEntity> pageServer(Integer page, Integer size, ServerPageDto serverPageDto) {
        Page<ServerEntity> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<ServerEntity> queryWrapper = new QueryWrapper<ServerEntity>().lambda()
                // 模糊匹配服务节点名
                .like(StringUtils.hasLength(serverPageDto.getServerName()), ServerEntity::getServerName,
                        SpecialCharacterUtil.escapeStr(serverPageDto.getServerName()))
                // 筛选服务器状态
                .eq(Objects.nonNull(serverPageDto.getStatus()), ServerEntity::getStatus, serverPageDto.getStatus())
                .eq(ServerEntity::getDeleted, false)
                .orderByDesc(ServerEntity::getCreateTime)
                .orderByDesc(ServerEntity::getId);
        return this.page(pageParam, queryWrapper);
    }

    @Override
    public Boolean updateServer(ServerEntity serverEntity) {
        ExceptionUtil.checkParam(Objects.nonNull(serverEntity.getId()), "id不能为空");
        LambdaQueryWrapper<ServerEntity> queryWrapper = new QueryWrapper<ServerEntity>().lambda()
                .ne(ServerEntity::getId, serverEntity.getId())
                .eq(ServerEntity::getServerName, serverEntity.getServerName())
                .eq(ServerEntity::getDeleted, false);
        ExceptionUtil.checkParam(!this.baseMapper.exists(queryWrapper), "已存在同样的主机名称，请重新输入！");
        LambdaQueryWrapper<ServerEntity> queryIpWrapper = new QueryWrapper<ServerEntity>().lambda()
                .ne(ServerEntity::getId, serverEntity.getId())
                .eq(ServerEntity::getServerIp, serverEntity.getServerIp())
                .eq(ServerEntity::getServerPort, serverEntity.getServerPort())
                .eq(ServerEntity::getAccountName, serverEntity.getAccountName())
                .eq(ServerEntity::getDeleted, false);
        ExceptionUtil.checkParam(!this.baseMapper.exists(queryIpWrapper),
                "已存在IP地址、主机端口、用户名三项同时相同的主机信息，请重新输入！");
        return this.updateById(serverEntity);
    }

}
